iT邦幫忙

2021 iThome 鐵人賽

DAY 1
0
自我挑戰組

JavaScript 奇奇怪怪的核心觀念系列 第 1

(Day1)執行環境與執行堆疊

  • 分享至 

  • xImage
  •  

執行環境 (Execution context)

在 JS 世界中執行環境是根據不同 function ,做區分的不同的函示,執行環境會是不同的。

直接用個簡單例子,就可以看出這個觀念:

function FN1(){
const string = 'test'
console.log(string)
}
function FN2(){
console.log(string)
}
FN1() //test
FN2() //string is not defined
console.log(string) //string is not defined

如同上面範例中,FN2 函示中、以及全域底下是無法找到 FN1 中的 string 常數,值得一提的是 JS 最底層的執行環境,就是全域本身(window) 。

執行堆疊 (Execution Stack)

執行堆疊是和上面執行環境相關的觀念,一般狀況下,函示執行完畢,函示記憶體便會釋放,比如這個範例:

function FN1(){
	console.log('FN1')
}
function FN2(){
	console.log('FN2')
}
FN1()
FN2()

範例的執行順序就會是:
執行 FN1 函示 ⇒ FN1 函示執行完畢,釋放記憶體 ⇒ 執行 FN2 函示 ⇒ FN2 函示執行完畢,釋放記憶體 。
當然這是一般狀況,如果我們函示中又『呼叫』了另外的函示,那麼就會造成執行堆疊的狀況,比如這個範例:

function FN1(parmNum){
  const number1 = parmNum + 1
  FN2(number1)
}
function FN2(parmNum){
  const number2 = parmNum + 1
	FN3(number2)
	}
function FN3(parmNum){
  const number3 = parmNum + 1
	}
FN1(1)

這邊可以使用 chrome 瀏覽器的 Sources 功能來觀察 執行堆疊 狀況:
執行堆疊.gif
(這邊要注意的是圖中的 Call Stack 狀況,Call Stack 就是執行堆疊狀態)

從上面 GIF 可以發現,FN1() 呼叫了 FN2(), 這種函示呼叫另一個函示時,Call Stack 就會一層一層疊起來,而這個堆疊順序是根據 『怎麼呼叫函示』有關,而非函示的宣告順序,因此根據程式碼執行堆疊順序就會是:
FN1()FN2()FN3()

而上面有提到函示執行完畢,會將記憶體釋放,而堆疊後的函示釋放順序則不會是一般人預期中的:
FN1()FN2()FN3()

而是由最後被執行的函示開始釋放,因此釋放的順序會是:
FN3()FN2()FN1()

參考文獻


下一篇
(Day2) 範圍鍊與提升
系列文
JavaScript 奇奇怪怪的核心觀念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言